package com.apes.bi.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.apes.bi.model.Applet;
import com.apes.bi.repository.AppletRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.plugin.esb.api.EsbRouter;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.plugin.websocket.WebSocketServer;
import com.apes.framework.rop.securityManager.SampleSessionManager;
import com.apes.framework.rop.session.SessionUtil;
import com.apes.framework.rop.session.SimpleSession;
import com.apes.framework.util.ApesConst;
import com.apes.framework.util.MapUtil;
import com.apes.framework.util.RopUtil;
import com.apes.oap.RopContext;
import com.apes.oap.impl.SimpleRopRequestContext;
import com.apes.oap.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.Map;

@Service("messageResolveService")
public class MessageResolveService extends DomainService {
    @Autowired
    AppletRepository appletRepository;
    @Autowired
    AppletConnectStore appletConnectStore;


    /***
     * 消息推送（订阅/注销）
     * @param request
     */
    @Listener(topic = "event:ws.onMessage")
    public void onMessage(SimpleRequest request) {
        Map map = (Map) request.getData();
        JSONObject message;
        try{
            message = JSONObject.parseObject(map.get("message").toString());
        } catch (Exception e){
            return;
        }
        WebSocketServer wss = (WebSocketServer) map.get("wss");
        if( message.getString("topic").equals("ws.openAppletConnect") ){
            if( message.getString("postId") == null ) throw new RuntimeException("岗位信息不能为空");
            onOpen(wss, message);
        } else if(message.getString("topic").equals("ws.closeAppletConnect")){
            if( message.getString("postId") == null ) throw new RuntimeException("岗位信息不能为空");
            onClose(wss, message);
        }
    }

    /***
     * 连接关闭
     * @param request
     */
    @Listener(topic = "event:ws.onClose")
    public void onClose(SimpleRequest request) {
        Map map = (Map) request.getData();
        AppletConnectStore.onClose((WebSocketServer) map.get("wss"));
    }


    /***
     * 增加订阅推送列表
     * @param wss
     */
    public void onOpen(WebSocketServer wss, JSONObject message){
        AppletConnectStore.add(wss, message);
    }

    /***
     * 减少订阅推送列表
     * @param wss
     */
    public void onClose(WebSocketServer wss, JSONObject message){
        AppletConnectStore.remove(wss, message);
    }

    /***
     * 推送消息
     */
    public void sendMessage(){
        Map<String,List<AppletConnectStore.AppletConnect>> stringListMap = appletConnectStore.getGroupAppletConnent();
        stringListMap.forEach((key, value) -> {
            Applet applet = appletRepository.findOne(key);

            if(!Cache.needRunning(applet)) return;

            value.stream().forEach(appletConnect -> {
                try{
                    JSONObject apiReturn = new JSONObject();

                    // 传入对应的 Session 用于获取当前登录人员的权限体系 userId postId
                    apiReturn.put("obj",invoke(applet.getWidgetApi().getId(),ApesConst.METHOD_VERSION,
                            MapUtil.mapper("userId",appletConnect.getWss().getUserId()),  getSession(appletConnect)));

//                    apiReturn.put("obj","老子信你个鬼，你个糟老头子坏得很");
                    apiReturn.put("appletId",key);
                    apiReturn.put("topic","ws.appletMessage");
                    appletConnect.getWss().sendMessage(JSON.toJSONString(apiReturn));
                }catch (IOException e){
                    e.printStackTrace();
                }
            });
        });
    }


    /***
     * 功能：获取session
     */
    private Session getSession(AppletConnectStore.AppletConnect appletConnect){
        String sessionId = SessionUtil.getSessionId(appletConnect.getUserId(), appletConnect.getPostId());
        SimpleSession session = (SimpleSession) getBean(SampleSessionManager.class).getSession(sessionId);
        if(session == null) throw new RuntimeException("未查询到对应的session");
        return session;
    }



    /**
     * 功能：ESB服务方法
     */
    private static <T> T invoke(String method, String version, Object body, Session session) {
        RopContext ropContext = RopUtil.getRopContext();
        SimpleRopRequestContext context = new SimpleRopRequestContext(ropContext);
        context.addSession(session);
        context.setMethod(method);
        context.setVersion(version);
        SimpleRequest simpleRequest = new SimpleRequest();
        simpleRequest.setRopRequestContext(context);
        simpleRequest.setData(body);
        EsbRouter router = getBean(EsbRouter.class);
        return router.innerCall(simpleRequest);
    }
}
